package com.eazy.lkv2.web.controller;

import java.io.Serializable;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.ModelAndView;

import com.eazy.lkv2.core.SpringContext;
import com.eazy.lkv2.core.email.SystemMail;
import com.eazy.lkv2.core.util.ClassUtil;
import com.eazy.lkv2.core.web.utils.Bundle;
import com.eazy.lkv2.core.web.utils.DateUtils;
import com.eazy.lkv2.core.web.utils.JsonKsy;
import com.eazy.lkv2.core.web.utils.PageData;
import com.eazy.lkv2.core.web.utils.RedisUtil;
import com.eazy.lkv2.core.web.utils.StrKit;
//import com.eazy.lkv2.core.web.utils.StringEscapeEditor;
import com.eazy.lkv2.web.entity.User;
import com.eazy.lkv2.web.redis.Redis;
import com.eazy.lkv2.web.shiro.UserUtil;
import com.eazy.lkv2.web.support.ActionRequest;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.exceptions.JedisConnectionException;

/**
 * @author jzx
 * @desc controller 基础操作类
 * @date 2016.3.19
 * 
 *       public abstract class BaseController<T> extends CrudController<T> {
 * 
 */
public abstract class BaseController<Entity, PK extends Serializable> extends SpringContext<Entity, PK> {

	protected Logger logger = LoggerFactory.getLogger(getClass());

	protected HttpServletRequest request;
	protected HttpServletResponse response;
	protected static StrKit StrUtils;
	
	public String getPara(String name) {
		return getRequest().getParameter(name);
	}

	public String getPara(String name, String defaultValue) {
		return ActionRequest.getPara(name, defaultValue, getRequest());
	}

	public Integer getParaToInt(String name) {
		return parseInt((getRequest().getParameter(name)));
	}

	public Long getParaToLong(String name) {
		return parseLong(getRequest().getParameter(name));
	}

	public Double getParaToDouble(String name) {
		return parseDouble(getRequest().getParameter(name));
	}

	public String[] getParaValues(String key) {
		return getRequest().getParameterValues(key);
	}

	public String getParaFormatDate(String name) {
		return parseDate(getRequest().getParameter(name));
	}

	public Map<String, String> getPageData(HttpServletRequest request) {
		return new PageData(request).getColumns();
	}

	public Map<String, String> getPageData() {
		return getPage().getColumns();
	}

	private PageData getPage() {
		return new PageData(getRequest());
	}

	public void setAttr(String key, Object value) {
		getRequest().setAttribute(key, value);
	}

	public void setAttrs(Map<String, Object> map) {
		ActionRequest.setAttrs(getRequest(), map);
	}

	public Object getAttr(String name) {
		return getRequest().getAttribute(name);
	}

	public Object getAttrSession(String name) {
		return getSession().getAttribute(name);
	}

	public String getAttrSessionToStr(String name) {
		return getSession().getAttribute(name).toString();
	}

	public void removeAttrSession(String name) {
		getSession().removeAttribute(name);
	}

	public void setAttrSession(String name, Object value) {
		getSession().setAttribute(name, value);
	}

	public void renderResult(boolean result) {
		if (result) {
			renderJson200();
		} else {
			renderJson500();
		}
	}

	public void renderResult(String result) {
		if (result != null) {
			renderJson200();
		} else {
			renderJson500();
		}
	}

	public void renderJson200() {
		renderJson("{\"code\":200}");
	}

	public void renderJson500() {
		renderJson("{\"code\":500}");
	}

	public void renderJsonError(String msg) {
		renderJson("{\"msg\":\" " + msg + " \"}");
	}

	public void renderJson(String data) {
		ActionRequest.renderJson(data, getResponse());
	}

	public void renderJson(Object data) {
		ActionRequest.renderJson(JsonKsy.converMapToJson(data), getResponse());
	}

	public void renderWord(String fileName, String columnName, List<String[]> list1) {
		renderWEP(fileName, columnName, list1, 1);
	}

	public void renderExcel(String fileName, String columnName, List<String[]> list1) {
		renderWEP(fileName, columnName, list1, 2);
	}

	public void renderPdf(String fileName, String columnName, List<String[]> list1) {
		renderWEP(fileName, columnName, list1, 3);
	}

	private void renderWEP(String fileName, String columnName, List<String[]> list1, int type) {
		ActionRequest.renderWEP(fileName, columnName, list1, type, getResponse());
	}

	public List<Map<String, Object>> toGson(String data) {
		Gson gson = new Gson();
		return gson.fromJson(data, new TypeToken<List<Map<String, Object>>>() {}.getType());
	}

	public <T> List<T> toGson(String data, Class<T> clz) {
		Gson gson = new Gson();
		return gson.fromJson(data, new TypeToken<T>() {}.getType());
	}

	public String toJson(Object src) {
		Gson gson = new Gson();
		return gson.toJson(src);
	}

	/**
	 * 拿到一些时间的简单调用
	 */
	public String getTimeNow() {
		return DateUtils.getNowTime();
	}

	public Timestamp getSysTimestamp() {
		return DateUtils.getSysTimestamp();
	}

	/**
	 * 拿到系统当前用户信息
	 */
	public User getCurrentUser() {
		return UserUtil.getCurrentUser();
	}

	/**
	 * 拿到系统缓存信息
	 */
	public String getCatch(String catchKey) {
		return Redis.getCatch(catchKey, getJedis());
	}

	public Object getCatch(Object catchKey) {
		return Redis.getCatch(catchKey, getJedis());
	}

	/**
	 * 判断缓存是否存在
	 */
	public boolean existsCatch(String catchKey) {
		return Redis.existsCatch(catchKey, getJedis());
	}

	/**
	 * 放置缓存信息
	 */
	public void putCatch(String catchKey, String catchValue) {
		Redis.putCatch(catchKey, catchValue, getJedis());
	}

	/**
	 * redis链接检测
	 */
	private Jedis getJedis() {
		Jedis jedis = null;
		try {
			jedis = RedisUtil.getJedis();
		} catch (JedisConnectionException ex) {
			logger.error("redis 服务器连接失败：", ex);
			SystemMail.getInstance().sendText("系统报告", "redis 服务器连接失败：" + ex, "testlksy@163.com");
		}
		return jedis;
	}

	/**
	 * view show
	 */
	public ModelAndView getSuccess(String viewName) {
		ModelAndView modelAndView = getModelViewInstances();
		modelAndView.setViewName(viewName);
		return modelAndView;
	}

	public <T> ModelAndView getSuccess(String viewName, T newinstances) {
		return getSuccess(viewName).addAllObjects(convertObj2Map(newinstances));
	}

	public ModelAndView getModelView() {
		return getModelViewInstances();
	}

	public Map<String, Object> getModel() {
		return getModelView().getModel();
	}

	public ModelAndView getSuccess(String viewName, String attributeName, Object attributeValue) {
		return this.getSuccess(viewName).addObject(attributeName, attributeValue);
	}

	public void addObject(String attributeName, Object attributeValue) {
		getModelViewInstances().addObject(attributeName, attributeValue);
	}

	public void addAllObjects(Map<String, ?> modelMap) {
		getModelViewInstances().addAllObjects(modelMap);
	}

	private ModelAndView view;
	
	private ModelAndView getModelViewInstances() {
		if(view ==null) {
			view = new ModelAndView();
		}
		return view;
	}

	/**
	 * 简单转换
	 */
	public Integer parseInt(String val) {
		return Bundle.convInt(val);
	}

	public Long parseLong(String val) {
		return Bundle.convLong(val);
	}

	public Double parseDouble(String val) {
		return Bundle.convDouble(val);
	}

	public String parseDate(String val) {
		return DateUtils.parseDate(DateUtils.yyyyMMdd, val);
	}

	public <T> Map<String, Object> convertObj2Map(T obj) {
		return ClassUtil.convertObj2Map(obj);
	}

	public String parseStr(Integer val) {
		return Bundle.convStr(val);
	}

	@InitBinder
	public void initBinder(ServletRequestDataBinder binder) {
		/**
		 * 自动转换日期类型的字段格式
		 */
		binder.registerCustomEditor(Date.class,
				new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"), true));

		/**
		 * 防止XSS攻击
		 */
		// binder.registerCustomEditor(String.class, new
		// StringEscapeEditor(true, true));
	}

	@ModelAttribute
	private void init(HttpServletRequest request, HttpServletResponse response) {
		this.request = request;
		this.response = response;
	}

	public HttpServletResponse getResponse() {
		HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
				.getResponse();
		return response;
	}

	public HttpServletRequest getRequest() {
		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
				.getRequest();
		return request;
	}

	public HttpSession getSession() {
		return getRequest().getSession();
	}
}
